home *** CD-ROM | disk | FTP | other *** search
- How to programm SYSEX in Bars&Pipes Tools
-
- by Alfred Faust j.k.dax@tonline.de
-
-
- First: I'm a german man, and I am not so good in the english language
-
- In the "Rules for Tools" manual I found the sentence:
-
- (In the capture :"Events, Clips, & Tracks - Events - 'type'")
-
- "... Only 'EVENT_VOICE' Events flow through the PipeLine; therefore Tools need
- only concern themselves with this one type. ... "
-
- That isn't right. 'EVENT_SYSX' Events are also flows through the Pipeline. I
- found out how to handle this events, sending directly through the PipeLine and
- writing them in the track.
-
- Here is the result of my (guess)work.
-
- First make a string that hold the sysex:
-
- {
- char *sysex;
- ...
-
- sysex = "F07E7F0901F7"; //this is the Geral-MIDI Reset
-
- ...
-
- }
-
- or:
-
- {
- char *sysex;
- storage[16];
-
- ...
-
- sprintf(storage, "F07E7F0901F7");
- sysex = storage;
-
- ...
-
- }
-
- ( It is very important that you ALWAYS use STRINGS (char) - not int- or
- BYTE-values. You must ALWAYS translate (int or BYTE)-values into (char).
-
- Have a look at the source-codes of my XGTools. There you can also see, how to
- put a prop-gadget-value in the SysExString.
-
- One possibility:
-
- {
- char *sysex;
- storage[16];
- int value = 2;
- // this can be the value of a slider
-
- char hexstr[3][2]={"00","01","02"};
- //that are hexvalues !!!
-
- ...
-
- sprintf(storage, "F043104C020102%.2sF7", hexstr[value] );
-
-
- /*
- this is the sysex for REVERB-time in XG-Devices
- The "%.2" will be replaced by "02" from hexstr-array,
- and then written into storage.
-
- You can also write:
-
- sprintf(storage, "F043104C020102%02lxF7", value)
-
- in this case you don't need the "hexstr"
-
- The "%02lx" will replaced by the value. Always a 2 nibble hexbyte will be
- written on this place.
-
- Exapmle:
-
- A value of a slider(Prop-Gadget) is given as decimal "20".
- %02lx will be replaced by "14" as hexbyte.
- */
- sysex = storage;
-
- ... )
-
- For my routines it MUST be a string. Then put it on the way.
-
- These are all functions you need:
-
- //the clip-routines for writing in the track
-
- static BOOL lock_clip(struct Clip *clip) {
- Forbid();
- if (clip->locked == 0)
- {
- clip->locked = 1;
- Permit();
- return TRUE;
- }
- else
- {
- Permit();
- return FALSE;
- } }
-
- static void unlock_clip(struct Clip *clip) {
- clip->locked = 0; }
-
- //writes sysex into track
-
- static void insertsysex(char *buff, short size,
- struct MNXGTool *tool,const LONG time) {
- struct StringEvent *event;
- struct String *string;
-
- event = (struct StringEvent *) (*functions->allocevent)();
- if (event)
- {
- string = (struct String *) (*functions->myalloc)(size + 3, MEMF_CLEAR);
- if (string)
- {
- event->next = NULL;
- event->string = string;
- memcpy(string->string, buff, size);
- string->length = size + 2;
- event->type = EVENT_SYSX;
- event->status = MIDI_SYSX;
- event->time = time;
- event->tool = tool->tool.next;
- if (lock_clip(&(tool->tool.track->clip)))
- {
- event->next =
- (struct StringEvent *)tool->tool.track->clip.events.first;
-
- tool->tool.track->clip.events.first =
- (struct Event *)(*functions->sorteventlist)(event);
-
- unlock_clip(&(tool->tool.track->clip));
- }
- else
- {
- (*functions->freelist)(event);
- }
- }
- } }
-
- // the routine for sending SysEx-data thru the pipeline
-
- static void sendsysex(char *buff, short size,
- struct MNXGTool *tool, const LONG time) {
- struct StringEvent *event;
- struct String *string;
-
- event = (struct StringEvent *) (*functions->allocevent)();
- if (event)
- {
- string = (struct String *) (*functions->myalloc)(size + 3, MEMF_CLEAR);
- if (string)
- {
- event->string = string;
- memcpy(string->string, buff, size);
- string->length = size + 2;
- event->type = EVENT_SYSX;
- event->status = MIDI_SYSX;
- event->time = time;
- event->tool = tool->tool.next;
- WaitTOF();
- (*functions->qevent)(event);
- (*functions->myfree)(string);
- }
- } }
-
- // THE MOST IMPORTANT TRANSLATION-ROUTINE
-
- static void trans_hx(struct MNXGTool *tool,
- const LONG time, char *sysx, int sw) {
- LONG size;
- int a, b, x, y ;
- UBYTE abuf[32];
- char chr[4];
- char *zbuf = NULL;
- struct Event *sysx_event;
-
- /*
- translate sysexbuffer (there are single chars, with his own hexvalue)
- into hex (always two chars to one hexvalue)
-
- example: "F0"
- In the string there are two hexvalues :
- 0x46 for "F" in the ASCII-table
- 0x30 for "0" in the ASCII-table
- But we will send the hex-value "0xF0" AND NOT "0x46 0x30"
- so we must translate ... */
-
-
- size = strlen(sysx); zbuf = (char *)AllocVec(size+2, MEMF_ANY|MEMF_CLEAR);
- if(zbuf)
- {
- CopyMem(sysx, zbuf, size);
- b=0;
- for(a=0;a < size;a=a+2)
- {
- chr[0] = zbuf[a];
- chr[1] = zbuf[a+1];
-
- x=(isdigit((int)chr[0]))? (chr[0]&0xF) : ((chr[0]&0xDF)-55);
- y=(isdigit((int)chr[1]))? (chr[1]&0xF) : ((chr[1]&0xDF)-55);
- //this is the translationscore - don't touch !!!
-
- abuf[b++] = ((x<<4)|y);
- //writing with bitmanipulation
-
- }
-
- FreeVec(zbuf);
-
- if (sw == 0) sendsysex(abuf, b, tool, time);
- if (sw == 1) insertsysex(abuf, b, tool, time);
- //put hexdata away
-
- } }
-
-
- There are now to possibilities.
-
- 1. Sending through the PipeLine:
-
-
- {
- struct my_Tool *tool;
- // a pointer to your Tool-structure
-
- char *sysex;
- ...
-
- sysex = "F07E7F0901F7";
- //this is the Geral-MIDI Reset
-
-
- trans_hx(tool, functions->timenow, sysex, 0)
- // "0" = switch for sending
- ...
-
- }
-
- If you only need the sendsysex-routine the clip-routines are here not
- necessary.
-
-
- 2. Writing in the Track:
-
- {
- struct my_Tool *tool;
- // a pointer to your Tool-structure
-
- char *sysex;
-
- ...
-
- sysex = "F07E7F0901F7"; //this is the Geral-MIDI Reset
-
- if ((*functions->areyousure)("write to track ? Play-pointer on right place?"))
- //this is a nice question ...
-
- {
- if (!functions->running)
- // You CAN'T write into track, if the sequencer is running !!!
-
- {
- trans_hx(tool, functions->starttime, sysex, 1)
- // "1" = switch for writing
-
- }
- }
-
- ...
-
- }
-
- If you don't need my comments - kill them ...
-
- I hope my pain, sweat and many sleepless nights are not only useful for my own.
-